package paskal.ui.components;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.util.Map;

import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.plaf.basic.BasicListUI;

import paskal.ui.Style;

public class List<E> extends JList<E> implements Component {
	private static final long serialVersionUID = 4195274648325893426L;

	private Color selected = null;
	private Color active = null;
	private int activeIndex = 0;
	private Font selectedFont;
	private Font font;

	public List() {
		setBackground(new Color(0, 0, 0, 0));
		setOpaque(false);
	}

	@Override
	protected void paintComponent(Graphics g) {
		g.setColor(getBackground());
		g.fillRect(0, 0, getWidth(), getHeight());
		super.paintComponent(g);
	}

	@Override
	public void stylize(String selector) {
		Style.getInstance().styleThisShit(selector, this);
	}

	@Override
	public void setProperty(String key, Object value) {
		switch (key) {
		case "bounds": {
			setBounds((Rectangle) value);
			break;
		}
		case "color": {
			setForeground(new Color(Integer.parseInt(value.toString()
					.substring(1), 16)));
			break;
		}
		case "font": {
			@SuppressWarnings("unchecked")
			Map<String, Object> font = (Map<String, Object>) value;
			this.font = new Font(font.get("name").toString(),
					(int) font.get("style"), (int) font.get("size"));
			selectedFont = new Font(this.font.getName(), Font.BOLD,
					this.font.getSize());
			setFont(this.font);
			break;
		}
		case "selected": {
			@SuppressWarnings("unchecked")
			Map<String, Object> selected = (Map<String, Object>) value;
			this.selected = new Color(
					Integer.parseInt(selected.get("backgroundColor").toString()
							.substring(1), 16));
			break;
		}
		case "active": {
			@SuppressWarnings("unchecked")
			Map<String, Object> focused = (Map<String, Object>) value;
			this.active = new Color(Integer.parseInt(focused.get("color")
					.toString().substring(1), 16));
			break;
		}
		default:
			break;
		}
		setUI(new BasicListUI() {
			@SuppressWarnings("rawtypes")
			@Override
			protected void paintCell(Graphics g2, int row, Rectangle rowBounds,
					ListCellRenderer cellRenderer, ListModel dataModel,
					ListSelectionModel selModel, int leadIndex) {
				Graphics2D g = (Graphics2D) g2;
				g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
						RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
				// super.paintCell(g, row, rowBounds, cellRenderer, dataModel,
				// selModel, leadIndex);
				if (row == leadIndex) {
					g.setColor(selected);
					g.fillRect(rowBounds.x, rowBounds.y, rowBounds.width,
							rowBounds.height);
				}
				String text = "    " + (row + 1) + ". "
						+ dataModel.getElementAt(row).toString();
				g.setColor(getForeground());
				if (row == activeIndex) {
					g.setFont(selectedFont);
					g.setColor(active);
					text = "\u266b " + (row + 1) + ". "
							+ dataModel.getElementAt(row).toString();
				} else {
					g.setFont(font);
				}
				FontMetrics fm = g.getFontMetrics();
				g.drawString(text, rowBounds.x, rowBounds.y
						+ (rowBounds.height + fm.getAscent() - fm.getDescent())
						/ 2);
			}
		});
	}

	public int getActiveIndex() {
		return activeIndex;
	}

	public void setActiveIndex(int selectedIndex) {
		this.activeIndex = selectedIndex;
		repaint();
	}
}
